// CacheMemcached ( cache_memcached.js )
// License: MIT
// takeda.akihito(At)gmail.com
function CacheMemcached(args){
    this.socket   = new AsyncLineSocket();
    this.flag    = 0;
    this.exptime = 0;
    this._loopCount = 0;
    this.cmd;
    this.key;
    this.value;
    this._buff = [];
    this._getFunc = function(s){};
    this._replaceFunc = function(s){};
    this._addFunc = function(s){};
    this._setFunc = function(s){};
    this._deleteFunc = function(s){};
    this._flushAllFunc = function(s){};
    this._statsFunc =  function(s){};
    this.onlineErrorFunc = function(s){alert('error:'+s);};
    this.lastValue;
    this.host = args.server[0];
    this.port = args.server[1];
    if(args.exptime){this.exptime = args.exptime};
    if(args.flag){this.flag = args.flag};
    this.socket.connect(this.host,this.port);
    this.socket.onConnected  = function(){};
    var self =  this;
    this.socket.onLine = function ( strLine ) {
        self._loopCount++;
        self._buff.push(strLine);
        if( strLine == "ERROR" 
            || strLine == "NOT_STORED"
            || strLine == "NOT_FOUND"
            || strLine == "CLIENT_ERROR"
            || strLine == "SERVER_ERROR"){
             self.onlineErrorFunc(strLine);
        }
        var c = self.cmd.split(' ');
        switch ( c[0] )
        {
            case "get":
            {
                if( self._loopCount == 2){
                    var str = unescape(strLine);
                    self.lastValue = str;
                    self._getFunc(str);
                }
                if( self._loopCount == 1 && strLine == "END"){
                    // NO VALUE
                    self.lastValue = "";
                    self._getFunc("");
                }
                break;                
            }
            case "replace":
            {
                self._replaceFunc(strLine);
                break;                
            }   
            case "add":
            {
                self._addFunc(strLine);
                break;                
            }   
            case "set":
            {
                self._setFunc(strLine);
                break;                
            }   

            case "delete":
            {
                self._deleteFunc(strLine);
                break;                
            }
            case "flush_all":
            {
                self._flushAllFunc(strLine);
                break;                
            }
            case "stats":
            {
                if( strLine == "END" ){ 
                    self._statsFunc(self._buff);
                }
                break;                
            }
        }
    }

    this.replace = function (key,value,f) {
        if( f ){
            this._replaceFunc = f;
        }
        this._set('replace',key,value);
    }
    this.add = function (key,value,f) {
        if( f ){
            this._addFunc = f;
        }
        this._set('add',key,value);
    }
    this.set = function (key,value,f) {
        if( f ){
            this._setFunc = f;
        }
        this._set('set',key,value);
    }
    this._set = function(c,key,value){
        this.key      = key;
        this.value    = value.toString();
        this._sendInit();
        var esc_value = escape(this.value);
        this.cmd = new Array(c,this.key,this.flag,this.exptime,esc_value.length).join(' ');
        this.socket.sendLine( this.cmd );
        this.socket.sendLine(esc_value);
    } 
    this.get = function (key,f) {
        this.key      = key;
        if( f ){
            this._getFunc = f;
        }
        this._sendInit();
        this.cmd = new Array('get',this.key).join(' ');
        this.socket.sendLine( this.cmd );
    }
    this.remove = function (key,f) {
        this.key         = key;
        if( f ){
            this._deleteFunc = f;
        }
        this._sendInit();
        this.cmd = new Array('delete',this.key).join(' ');
        this.socket.sendLine( this.cmd );
    }
    this.flush_all = function(f){
        if( f ){
            this._flushAllFunc = f;
        }
        this._sendInit();
        this.cmd = 'flush_all';
        this.socket.sendLine( this.cmd );
    }
    this.stats = function(f){
        if( f ){
            this._statsFunc = f;
        }
        this.cmd = 'stats';
        this._sendInit();
        this.socket.sendLine( this.cmd );
    }
    this.quit = function(){
        this.cmd = 'quit';
        this._sendInit();
        this.socket.sendLine( this.cmd );
    }
    this.close = function(){
        this._sendInit();
        this.socket.sendLine( "quit" );
        this.socket.close();
    }
    this._sendInit = function(){
        this._buff = [];
        this._loopCount = 0;
    }
}


